import time

try:  # pragma: no cover - MicroPython-only modules
    from machine import Pin  # type: ignore
except ImportError:  # pragma: no cover - host execution guard
    Pin = None  # type: ignore

try:  # pragma: no cover - MicroPython-only modules
    from neopixel import NeoPixel  # type: ignore
except ImportError:  # pragma: no cover - host execution guard
    NeoPixel = None  # type: ignore

from slip import SlipStream

# This code runs on the PyDuinoESP32C3 board.

# 🛠️ Initialize SLIP stream (UART1 on GPIO0/1)
link = SlipStream(uart_id=1, uart_tx=0, uart_rx=1)

# ✨ Status LED (NeoPixel on GPIO8)
_STATUS_PIN = 8
_BRIGHTNESS = 0.5

def _scale_color(color):
    return tuple(int(component * _BRIGHTNESS) for component in color)

_STATUS_COLORS = (
    _scale_color((255, 0, 0)),
    _scale_color((0, 255, 0)),
    _scale_color((0, 0, 255)),
)
if NeoPixel is None or Pin is None:
    raise RuntimeError("NeoPixel support requires machine.Pin and neopixel modules")

_status_pixel = NeoPixel(Pin(_STATUS_PIN), 1)
_status_pixel[0] = (0, 0, 0)
_status_pixel.write()
_status_index = 0

# 📄 Load payload once
try:
    with open('text.txt', 'r') as f:
        payload = f.read().encode()  # Convert to bytes immediately
except OSError as e:
    print("⚠️ File error:", e)
    payload = b''

# ⏱️ Setup non-blocking send interval
SEND_INTERVAL_MS = 2000  # 2 seconds
last_send_time = time.ticks_ms()

# 🔄 Main loop
while True:
    if link.poll():  # Non-blocking check for incoming data
        frame = link.recv()
        if frame:
            print(frame.decode())
            color = _STATUS_COLORS[_status_index]
            _status_pixel[0] = color
            _status_pixel.write()
            _status_index = (_status_index + 1) % len(_STATUS_COLORS)

    # ⏳ Send payload periodically without blocking
    current_time = time.ticks_ms()
    if time.ticks_diff(current_time, last_send_time) >= SEND_INTERVAL_MS:
        link.send(payload)
        last_send_time = current_time